//
//  1-02.c
//  LearningOpenGL
//
//  Created by wangrui on 14-7-4.
//  Copyright (c) 2014年 PPS. All rights reserved.
//

/*
 *画基本图形 点，线，多边形
 */

#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
#include <stdio.h>

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated" //消除 ‘废弃的api’ 警告，GLUT已全部在Mac上废除，可用glfw替换



void drawSomething()
{
	//GL_POLYGON:画多边形; GL_POINTS:画点; GL_LINES:两个点两个点的画线段; GL_LINE_STRIP:连续的线段 v0-v1-v2
	//GL_LINE_LOOP 类似GL_LINE_STRIP 但是是闭合的; GL_TRIANGLES:分别用三个点话三角形
	glBegin(GL_TRIANGLES);
	glVertex2f(0.0, 0.0);
	glVertex2f(0.0, 3.0);
	glVertex2f(4.0, 3.0);
	glVertex2f(6.0, 1.5);
	glVertex2f(4.0, 0.0);
	glEnd();
}

void drawPoint()
{
	glPointSize(3.0); //3个像素大小,默认1,不能写在glBegin()后
	glBegin(GL_POINTS);
	glVertex2f(0.0, 3.0);
	glVertex2f(4.0, 3.0);
	glVertex2f(6.0, 1.5);
	glEnd();
}

void drawLine()
{
	glLineWidth(2.0);
	glBegin(GL_LINES);
	glVertex2f(0.0, 0.0);//窗口中心定为了原点
	glVertex2f(0.0, -20.0);
	glVertex2f(40.0, 30.0);
	glVertex2f(6.0, 1.5);
	glVertex2f(4.0, 0.0);
	glEnd();
}

#define DrawOneLine(x1,y1,x2,y2) \
		glBegin(GL_LINES);\
		glVertex2f((x1),(y1)); \
		glVertex2f((x2),(y2)); \
		glEnd();

void drawDashLine()
{
	glEnable(GL_LINE_STIPPLE); //用连续点划线,必须显式启用才能有作用
	
	glLineWidth(5.0);
	glLineStipple(1, 0x0101); //000000010000001: 绘制一个像素，留6个像素，再绘制一个像素.....
	DrawOneLine(5.0, 12.50, 15.0, 12.5);
	
	glLineStipple(1, 0x00FF);
	DrawOneLine(15.0, 12.5, 25.0, 12.5);
	
	glLineStipple(1, 0x1c47);
	DrawOneLine(25.0, 12.50, 35.0, 12.5);
	
	glDisable(GL_LINE_STIPPLE);
}

void drawPolygon()
{
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	
	glBegin(GL_POLYGON);
	glVertex2f(0.0, 0.0);
	glVertex2f(0.0, 3.0);
	glVertex2f(4.0, 3.0);
	glVertex2f(6.0, 1.5);
	glVertex2f(4.0, 0.0);
	glEnd();
}

void drawThoughPoniterArray()
{
	static GLfloat vertices[] = {
		2.5,2.5,
		10.0,32.5,
		17.5,2.5,
		17.5,32.5,
		25.0,2.5,
		32.5,32.5
	};
	
	static GLfloat colors[] = {
		1.0,0.2,0.2,
		0.2,0.2,1.0,
		0.8,1.0,0.2,
		0.75,0.75,0.75,
		0.35,0.35,0.35,
		0.5,0.5,0.5
	};
	
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_COLOR_ARRAY);
	
	
	glColorPointer(3, GL_FLOAT, 0, colors);
	glVertexPointer(2, GL_FLOAT, 0, vertices);
	
	glBegin(GL_TRIANGLES);
	glArrayElement(2);
	glArrayElement(3);
	glArrayElement(4);
	glEnd();
		
	/*
	 * 上面5行代码等价于
	 * 
	 * glBegin(GL_TRIANGLES);
	 * glColor3fv(colors +(2*3));//取偏移两个点
	 * glVertex2fv(vertices + (2*3));
	 
	 * glColor3fv(colors +(3*3));
	 * glVertex2fv(vertices + (3*3));
	 
	 * glColor3fv(colors +(4*3));
	 * glVertex2fv(vertices + (4*3));
	 *
	 */
}

void drawACube()
{
	static GLfloat vertices[] = {
		2.5,2.5,
		10.0,32.5,
		17.5,2.5,
		17.5,32.5,
		25.0,2.5,
		32.5,32.5
	};
	
	static GLfloat colors[] = {
		1.0,0.2,0.2,
		0.2,0.2,1.0,
		0.8,1.0,0.2,
		0.75,0.75,0.75,
		0.35,0.35,0.35,
		0.5,0.5,0.5
	};
	
	glEnableClientState(GL_COLOR_ARRAY);
	glEnableClientState(GL_VERTEX_ARRAY);
	
	glColorPointer(3, GL_FLOAT, 0, colors);
	glVertexPointer(2, GL_FLOAT, 0, vertices);

	
	/*
	 *相当于:
	 glBegin(mode);
	 for(i=0; i<count; i++)
		glArrayElement(indices[i]);
	 glEnd();
	 */
	static GLubyte frontIndices[] = {3,4,5,6}; //取第3个，4个，5个，6个点
	static GLubyte rightIndices[] = {1,2,6,5};
	static GLubyte bottomIndices[] = {0,1,5,4};
	static GLubyte backIndices[] = {0,3,2,1};
	static GLubyte leftIndices[] = {0,4,7,3};
	static GLubyte topIndices[] = {2,3,7,6};
//	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, frontIndices); //glDrawElements 不需要再写在glbegin之间
//	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, rightIndices);
//	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, bottomIndices);
//	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, backIndices);
//	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, leftIndices);
//	glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, topIndices);
	
    // 等价于上面的code
//	static GLubyte allIndices[] =
//	{
//		4,5,6,7,1,2,6,5,
//		0,1,5,4,0,3,2,1,
//		0,4,7,3,2,3,7,6
//	};
//	
//	glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, allIndices);
	
	
	
	/* glMultiDrawElements
	 * 下面写法等价于:
	 
		for(int i=0; i<primccount; i++) {
			if(count[i]>0)
			{
				glDrawElements(mode,count[i],type,indices[i])
			}
		}
	 
	 */
	const GLvoid * const totalIndices[] = {frontIndices,rightIndices,bottomIndices,backIndices,leftIndices,topIndices};
	GLsizei const count[] = {4,4,4,4,4,4};
	glMultiDrawElements(GL_QUADS, count, GL_UNSIGNED_BYTE, totalIndices, 6);
}

void display()
{
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0, 1.0, 1.0);
	
	//drawPoint();
	//drawLine();
	//drawDashLine();
	//drawPolygon();
	//drawThoughPoniterArray();
	drawACube();
	
	glFlush();//important
}

void initViewingValue()
{
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}

void windowSizeReshape(int w, int h)
{
	glViewport(0, 0, (GLsizei)w, (GLsizei)h);//坐标（0,0) size:(w,h)
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}


int main(int argc, char **argv)
{
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(300, 300);
	glutCreateWindow(*argv);
	initViewingValue();
	
	glutDisplayFunc(display);
	
	glutReshapeFunc(windowSizeReshape);
	
	//glEnable(GL_LIGHTING);
	//glDisable(GL_LINE_LOOP);
	
	//状态信息查询
	GLdouble out[3] = {};
	glGetDoublev(GL_CURRENT_COLOR, out);//查询当前设定的颜色值
	printf("%f,%f,%f\n", *out, *(out+1),*(out+2));
	
	glutMainLoop();
	
	return 0;
}

#pragma clang diagnostic pop

